Fix time reporting to guest.
authorkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Tue, 27 Mar 2007 10:47:20 +0000 (11:47 +0100)
committerkfraser@localhost.localdomain <kfraser@localhost.localdomain>
Tue, 27 Mar 2007 10:47:20 +0000 (11:47 +0100)
The recent change to guest time handling dropped a call to
update_vcpu_system_time(), leading to time-went-backwards messages and
guest hangs (the latter were observed only in 2.6.21-rc4 and only when
no serial console was in use).

Debugging the issue also revealed that some commented out debug
printk-s in x86's time handling code didn't compile under x86-64.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
Signed-off-by: Keir Fraser <keir@xensource.com>
xen/arch/x86/time.c
xen/common/domain.c
xen/common/schedule.c

index 905e73c1c9581a4e0960e332f5ea87b8ebb0e586..daba20ff391b2b867059599c4562aeb8d1a957bb 100644 (file)
@@ -670,14 +670,20 @@ static inline void version_update_end(u32 *version)
     (*version)++;
 }
 
-static inline void __update_vcpu_system_time(struct vcpu *v)
+void update_vcpu_system_time(struct vcpu *v)
 {
     struct cpu_time       *t;
     struct vcpu_time_info *u;
 
+    if ( v->vcpu_info == NULL )
+        return;
+
     t = &this_cpu(cpu_time);
     u = &vcpu_info(v, time);
 
+    if ( u->tsc_timestamp == t->local_tsc_stamp )
+        return;
+
     version_update_begin(&u->version);
 
     u->tsc_timestamp     = t->local_tsc_stamp;
@@ -688,13 +694,6 @@ static inline void __update_vcpu_system_time(struct vcpu *v)
     version_update_end(&u->version);
 }
 
-void update_vcpu_system_time(struct vcpu *v)
-{
-    if ( vcpu_info(v, time.tsc_timestamp) !=
-         this_cpu(cpu_time).local_tsc_stamp )
-        __update_vcpu_system_time(v);
-}
-
 void update_domain_wallclock_time(struct domain *d)
 {
     spin_lock(&wc_lock);
@@ -771,9 +770,10 @@ static void local_time_calibration(void *unused)
     local_irq_enable();
 
 #if 0
-    printk("PRE%d: tsc=%lld stime=%lld master=%lld\n",
+    printk("PRE%d: tsc=%"PRIu64" stime=%"PRIu64" master=%"PRIu64"\n",
            smp_processor_id(), prev_tsc, prev_local_stime, prev_master_stime);
-    printk("CUR%d: tsc=%lld stime=%lld master=%lld -> %lld\n",
+    printk("CUR%d: tsc=%"PRIu64" stime=%"PRIu64" master=%"PRIu64
+           " -> %"PRId64"\n",
            smp_processor_id(), curr_tsc, curr_local_stime, curr_master_stime,
            curr_master_stime - curr_local_stime);
 #endif
@@ -855,6 +855,8 @@ static void local_time_calibration(void *unused)
     t->stime_local_stamp  = curr_local_stime;
     t->stime_master_stamp = curr_master_stime;
 
+    update_vcpu_system_time(current);
+
  out:
     set_timer(&t->calibration_timer, NOW() + EPOCH);
 
index 3008a4cc9050e3683914f4990e72eb5a08dae53e..5e6cc3486ca103931bb16c6d0c8102c83362112b 100644 (file)
@@ -96,14 +96,16 @@ struct vcpu *alloc_vcpu(
 
     v->domain = d;
     v->vcpu_id = vcpu_id;
-    v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]);
     spin_lock_init(&v->pause_lock);
 
     v->runstate.state = is_idle_vcpu(v) ? RUNSTATE_running : RUNSTATE_offline;
     v->runstate.state_entry_time = NOW();
 
     if ( !is_idle_domain(d) )
+    {
         set_bit(_VCPUF_down, &v->vcpu_flags);
+        v->vcpu_info = shared_info_addr(d, vcpu_info[vcpu_id]);
+    }
 
     if ( sched_init_vcpu(v, cpu_id) != 0 )
     {
index c361261ae7be470149d2b90100150d04ca6110fe..0dee0d19fe19636877b9c77e77b155c016def98c 100644 (file)
@@ -659,11 +659,8 @@ static void schedule(void)
     stop_timer(&prev->periodic_timer);
 
     /* Ensure that the domain has an up-to-date time base. */
-    if ( !is_idle_vcpu(next) )
-    {
-        update_vcpu_system_time(next);
-        vcpu_periodic_timer_work(next);
-    }
+    update_vcpu_system_time(next);
+    vcpu_periodic_timer_work(next);
 
     TRACE_4D(TRC_SCHED_SWITCH,
              prev->domain->domain_id, prev->vcpu_id,